import fs from 'fs';
import path from 'path';
import p from '../../lib/p';
import { ServerApiFile } from '../../api-file/server-api-file';

const asyncHandler = `import asyncHandler from "express-async-handler"`
const jsonHandler = `function jsonHandler<T>(fn: (req: Request) => T) {
  return (req: Request, res: Response) => {
    const result = fn(req)
    res.json(result)
  }
}`
const schemaHandler = `function schemaHandler<D>(
  fn: (req: Request, res: Response, data: D) => void,
  schema: Zod.ZodSchema
) {
  return (req: Request, res: Response) => {
    const parsed = schema.parse(req.body)
    fn(req, res, parsed)
  }
}`
const asyncSchemaHandler = `function asyncSchemaHandler<D>(
  fn: (req: Request, res: Response, data: D) => Promise<void>,
  schema: Zod.ZodSchema
) {
  return asyncHandler(async (req: Request, res: Response) => {
    const parsed = schema.parse(req.body)
    await fn(req, res, parsed)
  })
}`
const jsonSchemaHandler = `function jsonSchemaHandler<D, T>(fn: (req: Request, data: D) => T, schema: Zod.ZodSchema) {
  return (req: Request, res: Response) => {
    const parsed = schema.parse(req.body)
    const result = fn(req, parsed)
    res.json(result)
  }
}`
const asyncJsonHandler = `function asyncJsonHandler<T>(fn: (req: Request) => Promise<T>) {
  return asyncHandler(async (req: Request, res: Response) => {
    const result = await fn(req)
    res.json(result)
  })
}`
const asyncJsonSchemaHandler = `function asyncJsonSchemaHandler<D,T>(fn: (req: Request, data: D) => Promise<T>, schema: Zod.ZodSchema) {
  return asyncHandler(async (req: Request, res: Response) => {
    const parsed = schema.parse(req.body)
    const result = await fn(req, parsed)
    res.json(result)
  })
}`


// API文件扫描和路由生成器
class ApiRouteGenerator {
  apiFiles: ServerApiFile[];
  apiDir: string;
  outputFile: string;

  constructor(apiDir: string, outputFile: string) {
    this.apiFiles = ServerApiFile.fromDirectory(apiDir);
    this.apiDir = apiDir;
    this.outputFile = outputFile;
  }


  // 生成路由代码
  generateRouteCode() {
    // 生成导入语句
    const apiRouteImports = this.apiFiles.map(file => {
      if (file.hasBodySchema) {
        return `import ${file.importName}, { bodySchema as ${file.importName}_bodySchema } from '${file.importPath}'`;
      } else {
        return `import ${file.importName} from '${file.importPath}'`;
      }
    })
    
    const handlers = new Set<string>();

    // 生成路由注册代码
    const routeRegistrations = this.apiFiles.map(file => {
      const method = file.method.toLowerCase();
      const args: string[]= [];
      if (file.hasBodySchema) {
        args.push(file.importName);
        args.push(file.importName + '_bodySchema');
      } else {
        args.push(file.importName);
      }

      let wrapper = ''
      if (file.isAsync) {
        handlers.add(asyncHandler);
        if (file.usesResponse) {
          if (file.hasBodySchema) {
            handlers.add(asyncSchemaHandler);
            wrapper = 'asyncSchemaHandler';
          } else {
            wrapper = 'asyncHandler';
          }
        } else {
          if (file.hasBodySchema) {
            handlers.add(asyncJsonSchemaHandler);
            wrapper = 'asyncJsonSchemaHandler';
          } else {
            handlers.add(asyncJsonHandler);
            wrapper = 'asyncJsonHandler';
          }
        }
      } else {
        if (file.usesResponse) {
          if (file.hasBodySchema) {
            handlers.add(schemaHandler);
            wrapper = 'schemaHandler';
          } else {
            wrapper = '';
          }
        } else {
          if (file.hasBodySchema) {
            handlers.add(jsonSchemaHandler);
            wrapper = 'jsonSchemaHandler';
          } else {
            handlers.add(jsonHandler);
            wrapper = 'jsonHandler';
          }
        }
      }
      if (wrapper) {
        return `app.${method}('${file.routePath}', ${wrapper}(${args.join(', ')}))`;
      }
      return `app.${method}('${file.routePath}', ${args.join(', ')})`;
    })
    
    // 生成导入语句
    return [
      '/* eslint-disable prettier/prettier */',
      `import { Express, Request, Response } from "express"`,
      ...apiRouteImports,
      ...Array.from(handlers).sort((a, b) => a.length - b.length),
      'export function api(app: Express) {',
      ...p(routeRegistrations),
      '}',
    ].join('\n');
  }

  // 保存生成的代码到文件
  generate() {
    try {
      const code = this.generateRouteCode();
      fs.writeFileSync(this.outputFile, code, 'utf8');
      console.log('✅ API路由代码已成功生成到:', this.outputFile);
      console.log('📝 共生成', this.apiFiles.length, '个路由');

      // 显示生成的路由列表
      console.log('\n📋 生成的路由列表:');
      this.apiFiles.forEach((file) => {
        const features = [];
        if (file.isAsync) features.push('async');
        if (file.hasBodySchema) features.push('bodySchema');
        if (file.usesResponse) features.push('response');
        const featureStr = features.length > 0 ? ` [${features.join(', ')}]` : '';
        console.log(`  ${file.method.padEnd(6)} ${file.routePath}${featureStr}`);
      });
    } catch (error: any) {
      console.error('❌ 生成路由代码时发生错误:', error.message);
    }
  }
}

/**
 * 生成 RESETful API 文件的路由注册代码
 * @param dir 需要扫描的 API 目录
 * @param output 输出的文件路径
 */
export default function apir(dir: string, output: string) {
  const generator = new ApiRouteGenerator(dir, output);
  generator.generate();
}
